home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr47 / 131_01.zip / APAR.C < prev    next >
Text File  |  1993-06-05  |  7KB  |  448 lines

  1. /*
  2.     ************************************************************
  3.                 ACRL Parser
  4.     ************************************************************
  5.  
  6.     W. Lemiszki                      9 Jan 1982
  7.  
  8.     Filename: apar.c                 BDS C v1.50
  9. */
  10.  
  11. #include "acrl.h"
  12.  
  13.  
  14. parse()
  15. {
  16.     xrel = prepost = ltyp = specflag = FALSE;    /* init for stmt */
  17.     codelen = 0;
  18.     errchar = ' ';
  19.  
  20. L1:    scan();                    /* scan 1st token */
  21.     if (class == EOL)
  22.         return;                /* empty line */
  23.  
  24.     if (class == IDENT)            /* if identifier scanned... */
  25.         {
  26.         labsav();            /* save label params */
  27.         scan();                /* and scan next */
  28.         }
  29.  
  30.     if (infunc  &&  type == ':')        /* label definition */
  31.         {
  32.         speclist(floc);
  33.         enter(LOCAL, idLAB+RELBIT, floc);
  34.         goto L1;            /* go parse rest of line */
  35.         }
  36.     else if (class == PSEUDO)
  37.         pseudo_op();
  38.     else if (infunc && class == MACHINE)
  39.         instruction();
  40.  
  41.     if (class != EOL)            /* check last token */
  42.         error('Q');            /* extra garbage */
  43.     if (ltyp)
  44.         error('L');            /* label not used */
  45. }
  46.  
  47.  
  48.  
  49.  
  50. /*
  51.  *    Process a pseudo op
  52.  *    -------------------
  53.  */
  54. pseudo_op()
  55. {
  56.     switch (type)
  57.         {
  58.         case psINCL:
  59.         include();
  60.         break;
  61.  
  62.         case psEQU:
  63.         equset(idEQU);
  64.         break;
  65.  
  66.         case psSET:
  67.         equset(idSET);
  68.         break;
  69.  
  70.         case psFUNC:
  71.         function();
  72.         break;
  73.  
  74.         case psFEND:
  75.         fend();
  76.         break;
  77.  
  78.         case psEND:
  79.         endstmt();
  80.         break;
  81.  
  82.         case psDB:
  83.         db();
  84.         break;
  85.  
  86.         case psDW:
  87.         dw();
  88.         break;
  89.  
  90.         case psDS:
  91.         ds();
  92.         break;
  93.         }
  94. }
  95.  
  96.  
  97.  
  98.  
  99. /*
  100.  *    Process INCLUDE statement
  101.  *    -------------------------
  102.  */
  103. include()
  104. {
  105.     if (incflag)                /* if already including... */
  106.         {
  107.         error('N');            /* nest error */
  108.         return;
  109.         }
  110.     scan();                    /* scan filename string */
  111.     if (class == STRING)
  112.         {
  113.         if (fopen(tokbuf, incfile) == ERROR)
  114.         fatal("Can't include %s\n",tokbuf);
  115.         linesav = linecnt;            /* save line # */
  116.         linecnt = 0;
  117.         incflag = TRUE;
  118.         scan();
  119.         }
  120.       else
  121.         error('Q');                /* no filename present */
  122. }
  123.  
  124.  
  125.  
  126. /*
  127.  *    Process EQU or SET statement
  128.  *    ----------------------------
  129.  */
  130. equset(idtyp)
  131. byte idtyp;
  132. {
  133.     scan();
  134.     speclist(value = expression());        /* list the value */
  135.     enter(infunc ? LOCAL : GLOBAL, idtyp + (xrel ? RELBIT : 0), value);
  136. }
  137.  
  138.  
  139.  
  140.  
  141. /*
  142.  *    Process FUNCTION definition
  143.  *    ---------------------------
  144.  */
  145. function()
  146. {
  147.     int xfn;
  148.  
  149.     if (infunc)                /* if already in a function */
  150.         {
  151.         error('N');            /* nest error */
  152.         return;
  153.         }
  154.  
  155.     if (++numfunc > 64)
  156.         fatal("Too many functions (64 max)\n");
  157.  
  158.     speclist(lc);                /* list output file address */
  159.     enter(FUNCS, idFUNC, numfunc);        /* add to function table */
  160.     infunc = TRUE;
  161.  
  162.     scan();
  163.     xfn = 0;                /* external funcs needed */
  164.     while (class == IDENT)            /* for each ext function... */
  165.         {
  166.         labsav();            /* save identifier params */
  167.         enter(LOCAL, idFUNC, ++xfn);    /* into local table */
  168.         nameout(lnam);            /* output name to codebuf */
  169.         scan();
  170.         if (type == ',')        /* eat the comma */
  171.             scan();
  172.         }
  173.     code(0);                /* end of external funcs */
  174.  
  175.     codew(flen[numfunc]);            /* output body length */
  176.     floc = 0;
  177.     rellen = 0;
  178.  
  179.     if (xfn)                /* if any ext funcs */
  180.         {
  181.         code(0xC3);            /* jmp around vectors */
  182.         codew(floc = 3*(xfn+1));
  183.         relbuf[rellen++] = 1;        /* this jmp is reloc */
  184.         while (xfn--)
  185.             {
  186.             code(0xC3);        /* output empty jmps */
  187.             codew(0);
  188.             }
  189.         }
  190.  
  191.     faddr[numfunc] = lc;            /* save crl file addr */
  192.     prepost = PRE;
  193. }
  194.  
  195.  
  196.  
  197.  
  198. /*
  199.  *    Process FEND statement
  200.  *    ----------------------
  201.  */
  202. fend()
  203. {
  204.     int i;
  205.  
  206.     if (!infunc)                /* must be in a function */
  207.         {
  208.         error('N');            /* nest error */
  209.         return;
  210.         }
  211.     scan();                    /* scan EOL */
  212.     speclist(flen[numfunc] = floc);        /* save (and list) func len */
  213.  
  214.     codew(rellen);                /* output rellocation list */
  215.     for (i=0; i<rellen; )
  216.         codew(relbuf[i++]);
  217.  
  218.     infunc = FALSE;
  219.     prepost = POST;
  220. }
  221.  
  222.  
  223.  
  224. /*
  225.  *    Process END statement
  226.  *    ---------------------
  227.  */
  228. endstmt()
  229. {
  230.     if (incflag)            /* illegal in include files */
  231.         {
  232.         error('N');        /* nest error */
  233.         return;
  234.         }
  235.     endflag = TRUE;
  236.     if (infunc)            /* illegal inside a function */
  237.         {
  238.         error('N');        /* nest error */
  239.         fend();            /* fake a FEND */
  240.         }
  241.     speclist(lc);            /* list the output file addr */
  242.     scan();                /* scan the EOL */
  243. }
  244.  
  245.  
  246.  
  247.  
  248. /*
  249.  *    Process DB statement
  250.  *    --------------------
  251.  */
  252. db()
  253. {
  254.     char *ptr;
  255.  
  256.     if (!infunc)
  257.         return;                /* Q error */
  258.     do
  259.         {
  260.         scan();
  261.         if (class == STRING && tokbuf[1])    /* if more than 1 char */
  262.         {
  263.         for (ptr = tokbuf; *ptr; )    /* copy to code buffer */
  264.             code(*ptr++);
  265.         scan();
  266.         }
  267.           else
  268.         code(expr8());            /* get 8 bit expression */
  269.         } while (type == ',');
  270. }
  271.  
  272.  
  273.  
  274. /*
  275.  *    Process DW statement
  276.  *    --------------------
  277.  */
  278. dw()
  279. {
  280.     if (!infunc)
  281.         return;                /* Q error */
  282.     do
  283.         {
  284.         scan();
  285.         codew(expr16());
  286.         } while (type == ',');
  287. }
  288.  
  289.  
  290.  
  291.  
  292. /*
  293.  *    Process DS statement
  294.  *    --------------------
  295.  */
  296. ds()
  297. {
  298.     int v;
  299.  
  300.     if (!infunc)
  301.         return;
  302.     speclist(floc);                /* list the address */
  303.     scan();
  304.     v = expression();
  305.     if (xrel)
  306.         {
  307.         error('T');            /* must not be reloc. */
  308.         xrel = FALSE;
  309.         v = 0;
  310.         }
  311.     floc += v;                /* adjust */
  312.     lc += v;                /* generate 0's */
  313. }
  314.  
  315.  
  316.  
  317.  
  318. /* SUPPORT ROUTINES */
  319.  
  320.  
  321. /* Save label parameters */
  322. labsav()
  323. {
  324.     char *strsave();
  325.  
  326.     if (type == idUND)            /* if undefined */
  327.         lnam = strsave(tokbuf);        /* save the name */
  328.         else
  329.         {
  330.         labid = id;            /* else save entry ptr */
  331.         lnam = labid->nam;
  332.         }
  333.     ltyp = type + (reloc ? RELBIT : 0);
  334. }
  335.  
  336.  
  337.  
  338. /* Define a user identifier */
  339. enter(level, type, value)
  340. int level;
  341. byte type;
  342. int value;
  343. {
  344.     if (ltyp == 0)                /* no label */
  345.         error('L');
  346.     else if (ltyp == idUND)            /* undefined ? */
  347.         install(level, lnam, IDENT, type, value);
  348.     else if ((~RELBIT & type) == idSET && (~RELBIT & ltyp) == idSET)
  349.         {
  350.         labid->val = value;        /* new 'set' value */
  351.         labid->typ = type;        /* maybe new RELBIT */
  352.         }
  353.     else if (!pass || type != ltyp)
  354.         {
  355.         error('M');            /* multiply defined */
  356.         labid->typ = idMUL;        /* flag in table */
  357.         }
  358.     else if (value != labid->val)
  359.         error('P');            /* phase error */
  360.     ltyp = 0;                /* clear label flag */
  361. }
  362.  
  363.  
  364.  
  365.  
  366. /* Statement error handling */
  367. error(c)
  368. char c;
  369. {
  370.     if (errchar != ' ')            /* keep 1st error */
  371.         return;
  372.     errchar = c;
  373.     ++errcnt;                /* count it */
  374. }
  375.  
  376.  
  377.  
  378. /* Set special value to list in address field */
  379. speclist(v)
  380. int v;
  381. {
  382.     specflag = TRUE;
  383.     specval = v;
  384. }
  385.  
  386.  
  387.  
  388. /* Byte to code buffer */
  389. code(datum)
  390. byte datum;
  391. {
  392.     codebuf[codelen++] = datum;
  393. }
  394.  
  395.  
  396.  
  397. /* Word to code buffer */
  398. codew(word)
  399. addr word;
  400. {
  401.     code(word & 0xFF);
  402.     code(word >> 8);
  403. }
  404.  
  405.  
  406.  
  407.  
  408. /* Scan an 8 bit expression */
  409. expr8()
  410. {
  411.     int v;
  412.  
  413.     v = expression();
  414.     if (xrel)
  415.         error('T');            /* must be absolute */
  416.     if (v >= -256  &&  v < 256)
  417.         return (v);
  418.     error('V');                /* out of range */
  419.     return (v & 0xFF);
  420. }
  421.  
  422.  
  423.  
  424. /* Scan an address expression */
  425. expr16()
  426. {
  427.     int v;
  428.  
  429.     if (class == IDENT && type == idFUNC)    /* external function */
  430.         {
  431.         v = value * 3;            /* its vector address */
  432.         scan();
  433.         xrel = TRUE;
  434.         if (class == OPERATOR)        /* no expressions allowed */
  435.             error('X');
  436.         }
  437.         else
  438.         v = expression();
  439.  
  440.     if (xrel)                /* add to reloc list */
  441.         relbuf[rellen++] = floc + codelen;
  442.  
  443.     return (v);
  444. }
  445.  
  446.  
  447. /*EOF*/
  448.